home *** CD-ROM | disk | FTP | other *** search
- /* Commands for the X11 interface to Xconq.
- Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995
- Stanley T. Shebs.
-
- Xconq is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version. See the file COPYING. */
-
- #include "conq.h"
- #include "xconq.h"
- extern int zoom_in_out PROTO ((Side *side, Map *map, int which));
-
- /* The command table is an array of all the commands. */
-
- typedef struct cmdtab {
- char fchar; /* character to match against */
- char *name; /* Full name of command */
- char *argtypes;
- void (*fn)(); /* pointer to command's function */
- char *help; /* short documentation string */
- } CmdTab;
-
- static void execute_named_command PROTO ((Side *side, Map *map, char *cmdstr));
- static int execute_named_command_from_table PROTO ((Side *side, Map *map,
- char *cmdstr,
- CmdTab *cmdtab));
- static void describe_commands PROTO ((int arg, char *key, char *buf));
- static void describe_command_table PROTO ((int arg, char *key, char *buf,
- CmdTab *cmdtab));
- static void x_build PROTO ((Side *side, Map *map, int cancel));
- static void x_distance PROTO ((Side *side, Map *map, int cancel));
- static void x_move_look PROTO ((Side *side, Map *map));
- static void x_move_dir PROTO ((Side *side, Map *map, Unit *unit));
- static void x_message PROTO ((Side *side, Map *map, int cancel));
- static void x_move_to PROTO ((Side *side, Map *map, int cancel));
- static void x_name PROTO ((Side *side, Map *map, int cancel));
- static void x_others PROTO ((Side *side, Map *map, int cancel));
- static void x_resign PROTO ((Side *side, Map *map, int cancel));
- static void x_resign_2 PROTO ((Side *side, Map *map, int cancel));
- static void x_leave_game PROTO ((Side *side, Map *map, int cancel));
- static void x_kill_game PROTO ((Side *side, Map *map, int cancel));
- static void x_save_2 PROTO ((Side *side, Map *map, int cancel));
- static void x_save_1 PROTO ((Side *side, Map *map, int cancel));
- static void x_save_1_1 PROTO ((Side *side, Map *map, int cancel));
- static void save_the_game PROTO ((Side *side));
- static void cmd_error PROTO ((Side *side, char *fmt, ...));
-
- char tmpkey;
-
- Map *tmpmap;
-
- #define C(c) ((c)-0x40)
-
- #undef DEF_CMD
- #define DEF_CMD(LETTER,NAME,ARGS,FN,HELP) { LETTER, NAME, ARGS, FN, HELP },
-
- /* Define a table of generic Xconq commands. */
-
- CmdTab commands[] = {
-
- #include "cmd.def"
-
- { 0, NULL, NULL, NULL, NULL }
- };
-
- /* Define a table of additional X-specific commands. */
-
- CmdTab xcommands[] = {
-
- #include "xcmd.def"
-
- { 0, NULL, NULL, NULL, NULL }
- };
-
- /* Search in command table and execute function if found, complaining if
- the command is not recognized. Many commands operate on the "current
- unit", and all uniformly error out if there is no current unit, so put
- that test here. */
-
- static int execute_command_from_table PROTO ((Side *side, Map *map, CmdTab *cmdtab));
-
- void
- execute_command(side, map)
- Side *side;
- Map *map;
- {
- int found;
-
- side->ui->beepcount = 0;
- /* Look through the X-specific command table. */
- found = execute_command_from_table(side, map, xcommands);
- if (!found) {
- /* Try the generic table. */
- found = execute_command_from_table(side, map, commands);
- }
- if (!found) {
- cmd_error(side, "unknown command key '%c'", map->inpch);
- }
- }
-
- static int
- execute_command_from_table(side, map, cmdtab)
- Side *side;
- Map *map;
- CmdTab *cmdtab;
- {
- CmdTab *cmd;
- char ch = map->inpch;
- void (*fn) PROTO ((Side *side, Map *map));
-
- for (cmd = cmdtab; cmd->name != NULL; ++cmd) {
- if (ch == cmd->fchar) {
- fn = cmd->fn;
- if (fn == NULL) {
- run_warning("no command function for %s (0x%x)?",
- cmd->name, ch);
- return TRUE;
- }
- tmpkey = ch;
- if (cmd->argtypes != NULL
- && cmd->argtypes[0] == 'U'
- && fn != do_delay /* hack */) {
- if (map->curunit != NULL) {
- (*fn)(side, map);
- } else {
- cmd_error(side, "No unit to command!");
- }
- } else {
- (*fn)(side, map);
- }
- /* Whatever might have happened, we *did* find the command. */
- return TRUE;
- }
- }
- return FALSE;
- }
-
- /* (should parse the command in useful ways) */
-
- static void
- execute_named_command(side, map, cmdstr)
- Side *side;
- Map *map;
- char *cmdstr;
- {
- int found;
-
- /* Look for the command name in the X-specific table. */
- found = execute_named_command_from_table(side, map, cmdstr, xcommands);
- if (!found) {
- /* Try the generic table. */
- found = execute_named_command_from_table(side, map, cmdstr, commands);
- }
- if (!found) {
- cmd_error(side, "unrecognized command name \"%s\"", cmdstr);
- }
- }
-
- static int
- execute_named_command_from_table(side, map, cmdstr, cmdtab)
- Side *side;
- Map *map;
- char *cmdstr;
- CmdTab *cmdtab;
- {
- CmdTab *cmd;
- void (*fn) PROTO ((Side *side, Map *map));
-
- /* Whack off leading whitespace. */
- while (*cmdstr && isspace(*cmdstr))
- ++cmdstr;
- for (cmd = cmdtab; cmd->name != NULL; ++cmd) {
- if (strcmp(cmdstr, cmd->name) == 0) {
- if ((fn = cmd->fn) == NULL) {
- run_warning("no command function for %s?", cmd->name);
- return TRUE;
- }
- tmpkey = cmd->fchar;
- (*fn)(side, map);
- /* Whatever might have happened, we *did* find the command. */
- return TRUE;
- }
- }
- return FALSE;
- }
-
- /* Describe all the commands. */
-
- static void
- describe_commands(arg, key, buf)
- int arg;
- char *key, *buf;
- {
- describe_command_table(arg, key, buf, commands);
- strcat(buf, "\n");
- describe_command_table(arg, key, buf, xcommands);
- }
-
- /* Describe all the commands to be found in a given table. */
-
- static void
- describe_command_table(arg, key, buf, cmdtab)
- int arg;
- char *key, *buf;
- CmdTab *cmdtab;
- {
- CmdTab *cmd;
-
- for (cmd = cmdtab; cmd->name != NULL; ++cmd) {
- if (cmd->fchar != '\0') {
- if (cmd->fchar < ' ' || cmd->fchar > '~') {
- tprintf(buf, "^%c", (cmd->fchar ^ 0x40));
- } else {
- tprintf(buf, " %c", cmd->fchar);
- }
- strcat(buf, " ");
- strcat(buf, cmd->help);
- strcat(buf, "\n");
- }
- }
- for (cmd = cmdtab; cmd->name != NULL; ++cmd) {
- if (cmd->fchar == '\0') {
- strcat(buf, "\"");
- strcat(buf, cmd->name);
- strcat(buf, "\"");
- strcat(buf, " ");
- strcat(buf, cmd->help);
- strcat(buf, "\n");
- }
- }
- }
-
- /* Definitions of all the command functions. */
-
- void
- do_add_player(side, map)
- Side *side;
- Map *map;
- {
- notify(side, "can't add new players yet");
- }
-
- void
- do_add_terrain(side, map)
- Side *side;
- Map *map;
- {
- notify(side, "can't add terrain yet");
- }
-
- void
- do_ai_side(side, map)
- Side *side;
- Map *map;
- {
- if (side_has_ai(side)) {
- set_side_ai(side, NULL);
- } else {
- set_side_ai(side, "mplayer");
- }
- }
-
- void
- do_attack(side, map)
- Side *side;
- Map *map;
- {
- notify(side, "no generic attacks yet");
- }
-
- void
- do_auto(side, map)
- Side *side;
- Map *map;
- {
- Unit *unit = map->curunit;
-
- if (unit->plan) {
- unit->plan->autotask = !unit->plan->autotask;
- /* finish move under automatic control */
- }
- }
-
- void
- do_build(side, map)
- Side *side;
- Map *map;
- {
- int n, u, u2, possibles[MAXUTYPES], numtypes, ufirst;
- Unit *unit = map->curunit;
-
- u = unit->type;
- if (!can_build(unit)) {
- cmd_error(side, "This unit can't build anything!");
- return;
- }
- if (unit->transport != NULL
- && !uu_occ_can_build(unit->transport->type, u)) {
- cmd_error(side, "This unit can't build anything while inside another unit!");
- return;
- }
- numtypes = 0;
- for_all_unit_types(u2) {
- if (uu_acp_to_create(u, u2) > 0) {
- possibles[u2] = 1;
- ++numtypes;
- ufirst = u2;
- } else {
- possibles[u2] = 0;
- }
- }
- switch (numtypes) {
- case 0:
- cmd_error(side, "Nothing to build!");
- break;
- case 1:
- /* Only one type to build - do it. */
- n = map->argint;
- if (n < 0)
- n = 99;
- notify(side, "%s will build %d %s",
- unit_handle(side, unit), n, u_type_name(ufirst));
- push_build_task(unit, ufirst, n);
- break;
- default:
- /* Player has to choose a type to build. */
- map->argunitid = unit->id;
- ask_unit_type(side, map, "Type to build:", possibles, x_build);
- break;
- }
- }
-
- static void
- x_build(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- int u2, n;
- Unit *unit;
-
- if (cancel)
- return;
- if (map->inpch == '?') {
- notify(side, "Type a key or click on a unit type to select build.");
- map->modalhandler = x_build;
- return;
- }
- if (grok_unit_type(side, map, &u2)) {
- if (u2 != NONUTYPE) {
- unit = find_unit(map->argunitid);
- if (in_play(unit) && side_controls_unit(side, unit)) {
- n = map->argint;
- if (n < 0)
- n = 99;
- notify(side, "%s will build %d %s",
- unit_handle(side, unit), n, u_type_name(u2));
- push_build_task(unit, u2, n);
- }
- }
- } else {
- /* beep? */
- }
- }
-
- void
- do_clear_plan(side, map)
- Side *side;
- Map *map;
- {
- Unit *unit = map->curunit;
-
- set_unit_plan_type(side, unit, PLAN_NONE);
- }
-
- void
- do_copying(side, map)
- Side *side;
- Map *map;
- {
- notify(side, "You may copy freely. See the file COPYING.");
- }
-
- void
- do_delay(side, map)
- Side *side;
- Map *map;
- {
- Unit *unit = map->curunit;
-
- if (unit != NULL) {
- if (unit->plan)
- delay_unit(unit, TRUE);
- } else {
- unit = find_next_awake_mover(side, map->curunit);
- if (unit != map->curunit) {
- set_current_unit(side, map, unit);
- } else {
- cmd_error(side, "No next awake mover found.");
- }
- }
- }
-
- void
- do_detach(side, map)
- Side *side;
- Map *map;
- {
- notify(side, "can't detach yet");
- }
-
- void
- do_detonate(side, map)
- Side *side;
- Map *map;
- {
- Unit *unit = map->curunit;
-
- prep_detonate_action(unit, unit, unit->x, unit->y, unit->z);
- }
-
- void
- do_dir(side, map)
- Side *side;
- Map *map;
- {
- switch (map->curtool) {
- case looktool:
- if (map->argint < 0)
- map->argint = 1;
- x_move_look(side, map);
- break;
- case movetool:
- case unitmovetool:
- if (map->curunit != NULL) {
- x_move_dir(side, map, map->curunit);
- } else {
- cmd_error(side, "No unit to move!");
- }
- break;
- }
- }
-
- void
- do_dir_multiple(side, map)
- Side *side;
- Map *map;
- {
-
- switch (map->curtool) {
- case looktool:
- if (map->argint < 0)
- map->argint = 10;
- x_move_look(side, map);
- break;
- case movetool:
- case unitmovetool:
- map->argint = 9999;
- if (map->curunit != NULL) {
- x_move_dir(side, map, map->curunit);
- } else {
- cmd_error(side, "No unit to move!");
- }
- break;
- }
- }
-
- static void
- x_move_look(side, map)
- Side *side;
- Map *map;
- {
- char *dc;
- int dir, nx, ny;
- Unit *unit;
-
- dc = strchr(dirchars, tmpkey);
- if (dc == NULL) {
- dc = strchr(dirchars, lowercase(tmpkey));
- if (dc == NULL) {
- cmd_error(side, "what direction is that?!?");
- return;
- }
- }
- dir = dc - dirchars;
- if (!point_in_dir_n(map->curx, map->cury, dir, map->argint, &nx, &ny)) {
- beep(side);
- return;
- }
- /* (should share with move_look) */
- clear_current(side, map);
- unit = unit_at(nx, ny);
- if (unit != NULL
- && (side_controls_unit(side, unit) || g_see_all())) {
- set_current_unit(side, map, unit);
- } else {
- set_current_xy(side, map, nx, ny);
- }
- }
-
- static void
- x_move_dir(side, map, unit)
- Side *side;
- Map *map;
- Unit *unit;
- {
- char *dc;
- int dir;
- int n = map->argint;
- int x, y;
-
- dc = strchr(dirchars, tmpkey);
- if (dc == NULL) {
- dc = strchr(dirchars, lowercase(tmpkey));
- if (dc == NULL) {
- cmd_error(side, "what direction is that?!?");
- return;
- }
- }
- if (!unit->act || !unit->plan) { /* use a more sophisticated test? */
- /* ??? can't act ??? */
- return;
- }
- dir = dc - dirchars;
- if (n > 1) {
- DGprintf("Ordering %s to move %d %s\n",
- unit_desig(unit), n, dirnames[dir]);
- set_movedir_task(unit, dir, n);
- } else {
- if (!point_in_dir(unit->x, unit->y, dir, &x, &y)) {
- return;
- }
- if (!advance_into_cell(side, unit, x, y, NULL)) {
- beep(side);
- }
- if (in_play(unit)) {
- map->curx = unit->x; map->cury = unit->y;
- }
- /* make sure we don't wander too close to the edge... */
- /* (this probably should not be here) */
- x = map->curx - map->vx; y = map->cury - map->vy;
- if (y < 3 || y > map->vh - 3) {
- recenter(side, map, map->curx, map->cury);
- }
- }
- }
-
- /* Get rid of a unit. */
-
- void
- do_disband(side, map)
- Side *side;
- Map *map;
- {
- int u;
- Unit *unit = map->curunit;
-
- if (!in_play(unit))
- return;
- u = unit->type;
- #ifdef DESIGNERS
- /* A designer can take out any unit, no questions asked. */
- if (side->designer) {
- kill_unit(unit, -1);
- return;
- }
- #endif /* DESIGNERS */
- if (u_hp_per_disband(u) > 0) {
- if (prep_disband_action(unit, unit)) {
- notify(side, "%s will go home.", unit_handle(side, unit));
- } else {
- cmd_error(side, "odd failure");
- }
- } else {
- cmd_error(side, "You can't just get rid of the %s!", u_type_name(u));
- }
- }
-
- void
- do_distance(side, map)
- Side *side;
- Map *map;
- {
- save_cur(side, map);
- ask_position(side, map, "Distance to where?", x_distance);
- }
-
- static void
- x_distance(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- int x, y, dist;
-
- if (cancel)
- return;
- if (map->inpch == '?') {
- notify(side, "Not being helpful yet.");
- map->modalhandler = x_distance;
- return;
- }
- if (grok_position(side, map, &x, &y)) {
- if (in_area(x, y)) {
- dist = distance(map->savedcurx, map->savedcury, x, y);
- notify(side, "The distance is %d cells.", dist);
- }
- restore_cur(side, map);
- } else {
- map->modalhandler = x_distance;
- /* beep? */
- }
- }
-
- void
- do_end_turn(side, map)
- Side *side;
- Map *map;
- {
- finish_turn(side);
- }
-
- void
- do_fire(side, map)
- Side *side;
- Map *map;
- {
- int sx, sy, x, y;
- Map *map2;
- Unit *other;
- Unit *unit = map->curunit;
-
- if (!in_play(unit))
- return;
-
- sx = side->ui->sxdown;
- sy = side->ui->sydown;
- map2 = side->ui->mapdown;
-
- if (x_nearest_cell(side, map2, sx, sy, &x, &y)) {
- if (x != unit->x || y != unit->y) {
- if (unit->act && unit->plan) { /* (should be more sophisticated?) */
- other = unit_at(x, y);
- if (other != NULL) {
- /* There's a unit to fire at. */
- if (other->side == unit->side) {
- beep(side);
- } else {
- prep_fire_at_action(unit, unit, other, -1);
- }
- } else {
- beep(side);
- }
- }
- }
- }
- }
-
- void
- do_fire_into(side, map)
- Side *side;
- Map *map;
- {
- beep(side);
- }
-
- void
- do_give(side, map)
- Side *side;
- Map *map;
- {
- int something = FALSE;
- int n, u, m, r, gift, actual;
- Unit *unit = map->curunit, *main = NULL;
- char buf[BUFSIZE];
-
- if (nummtypes == 0) {
- cmd_error(side, "No materials in this game!");
- return;
- }
- buf[0] = '\0';
- u = unit->type;
- main = unit->transport;
- if (main == NULL) {
- cmd_error(side, "Nothing to give to here!");
- return;
- }
- m = main->type;
- n = (map->argint < 0 ? 1 : map->argint);
-
- for_all_material_types(r) {
- gift = (n < 0 ? (um_storage_x(m, r) - main->supply[r]) : n);
- if (gift > 0) {
- something = TRUE;
- /* Be stingy if we're low */
- if (2 * unit->supply[r] < um_storage_x(u, r))
- gift = max(1, gift/2);
- actual = transfer_supply(unit, main, r, gift);
- tprintf(buf, " %d %s", actual, m_type_name(r));
- }
- }
- if (something) {
- notify(side, "%s gave%s.", unit_handle(side, unit), buf);
- } else {
- notify(side, "%s gave nothing.", unit_handle(side, unit));
- }
- }
-
- /* Give a unit to another side or make it independent. */
-
- /* (but giving to indep should be tested, otherwise might kill unit) */
-
- void
- do_give_unit(side, map)
- Side *side;
- Map *map;
- {
- int u;
- Unit *unit = map->curunit;
-
- u = unit->type;
- if (/* u_change_side(u) || */ side->designer) {
- /* unit_changes_side(unit, side_n(n), CAPTURE, PRISONER); */
- all_see_cell(unit->x, unit->y);
- } else {
- cmd_error(side, "You can't just give away the %s!", u_type_name(u));
- }
- }
-
- void
- do_help(side, map)
- Side *side;
- Map *map;
- {
- /* Compose the help node for commands and make it be the first one. */
- if (side->ui->curhelpnode == NULL) {
- add_help_node("commands", describe_commands, 0, firsthelpnode);
- side->ui->curhelpnode = firsthelpnode;
- }
- popup_help(side);
- }
-
- /* Send a short (1 line) message to another player. Some messages are
- recognized specially, causing various actions. */
-
- void
- do_message(side, map)
- Side *side;
- Map *map;
- {
- char prompt[BUFSIZE];
- Side *side2;
-
- side2 = side_n(map->argint);
- if (side == side2) {
- cmd_error(side, "You mumble to yourself.");
- return;
- }
- if (side2) {
- sprintf(prompt, "Say to %s: ", short_side_title(side2));
- } else {
- sprintf(prompt, "Broadcast to all: ");
- }
- map->argside = side2;
- ask_string(side, map, prompt, NULL, x_message);
- }
-
- static void
- x_message(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- char *msg;
- SideMask sidemask;
-
- if (cancel)
- return;
- if (grok_string(side, map, &msg)) {
- if (empty_string(msg)) {
- notify(side, "You keep your mouth shut.");
- sidemask = NOSIDES;
- } else if (map->argside == NULL) {
- notify(side, "You made the announcement \"%s\"", msg);
- sidemask = ALLSIDES;
- } else {
- notify(side, "Your message was sent.");
- sidemask = add_side_to_set(map->argside, NOSIDES);
- }
- if (!empty_string(msg) && sidemask != NOSIDES)
- send_message(side, sidemask, msg);
- } else {
- map->modalhandler = x_message;
- }
- }
-
- /* Set unit to move to a given location. */
-
- /* The command proper. */
-
- void
- do_move_to(side, map)
- Side *side;
- Map *map;
- {
- Unit *unit = map->curunit;
-
- map->argunitid = unit->id;
- save_cur(side, map);
- ask_position(side, map, "Move to where?", x_move_to);
- }
-
- static void
- x_move_to(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- int x, y;
- Unit *unit;
-
- if (cancel)
- return;
- if (grok_position(side, map, &x, &y)) {
- unit = find_unit(map->argunitid);
- #ifdef DESIGNERS
- if (side->designer) {
- designer_teleport(unit, x, y);
- } else
- #endif /* DESIGNERS */
- if (in_play(unit)) {
- set_moveto_task(unit, x, y);
- } else {
- beep(side);
- }
- restore_cur(side, map);
- } else {
- map->modalhandler = x_move_to;
- }
- }
-
- /* Name/rename the current unit. */
-
- void
- do_name(side, map)
- Side *side;
- Map *map;
- {
- char tmpbuf[BUFSIZE];
- Unit *unit = map->curunit;
-
- map->argunitid = unit->id;
- sprintf(tmpbuf, "New name for %s:", unit_handle(side, unit));
- ask_string(side, map, tmpbuf, unit->name, x_name);
- }
-
- static void
- x_name(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- char *name;
- Unit *unit;
-
- if (cancel)
- return;
- if (grok_string(side, map, &name)) {
- unit = find_unit(map->argunitid);
- if (in_play(unit) && side_controls_unit(side, unit)) {
- set_unit_name(side, unit, name);
- } else {
- cmd_error(side, "Nothing could be named!");
- }
- } else {
- map->modalhandler = x_name;
- }
- }
-
- /* This is a command to examine all occupants and suboccupants, in an
- inorder fashion. */
-
- /* Should have an option to open up a list window that shows everything
- all at once. */
-
- void
- do_occupant(side, map)
- Side *side;
- Map *map;
- {
- Unit *nextup;
- Unit *unit = map->curunit;
-
- if (unit->occupant != NULL) {
- set_current_unit(side, map, unit->occupant);
- } else if (unit->nexthere != NULL) {
- set_current_unit(side, map, unit->nexthere);
- } else {
- nextup = unit->transport;
- if (nextup != NULL) {
- while (nextup->transport != NULL && nextup->nexthere == NULL) {
- nextup = nextup->transport;
- }
- if (nextup->nexthere != NULL)
- set_current_unit(side, map, nextup->nexthere);
- if (nextup->transport == NULL)
- set_current_unit(side, map, nextup);
- } else {
- /* This is a no-op if there is no stacking within a hex. */
- set_current_unit(side, map, unit_at(unit->x, unit->y));
- }
- }
- }
-
- void
- do_other(side, map)
- Side *side;
- Map *map;
- {
- ask_string(side, map, "Command:", "", x_others);
- }
-
- static void
- x_others(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- char *cmd;
-
- if (cancel)
- return;
- if (grok_string(side, map, &cmd)) {
- if (empty_string(cmd)) {
- notify(side, "No command");
- } else if (strcmp(cmd, "?") == 0) {
- do_help(side, map);
- /* (should go to command list specifically) */
- } else {
- execute_named_command(side, map, cmd);
- }
- } else {
- map->modalhandler = x_others;
- }
- }
-
- static PrintParameters *ps_pp = NULL;
-
- void
- do_print_view(side, map)
- Side *side;
- Map *map;
- {
- double conv;
-
- if (!ps_pp)
- ps_pp = (PrintParameters *) xmalloc(sizeof(PrintParameters));
-
- init_ps_print(ps_pp);
-
- /* convert to cm or in */
- if (ps_pp->cm) {
- conv = 72/2.54;
- } else {
- conv = 72;
- }
- ps_pp->cell_size /= conv;
- ps_pp->cell_grid_width /= conv;
- ps_pp->border_width /= conv;
- ps_pp->connection_width /= conv;
- ps_pp->page_width /= conv;
- ps_pp->page_height /= conv;
- ps_pp->top_margin /= conv;
- ps_pp->bottom_margin /= conv;
- ps_pp->left_margin /= conv;
- ps_pp->right_margin /= conv;
-
- popup_print_setup_dialog(side, ps_pp);
- #if 0
- /* dump the view */
- notify(side, "dumping view to file \"view.xconq\" ...");
- flush_output(side);
- dump_ps_view(side, ps_pp, "view.xconq");
- notify(side, "... done.");
- #endif
- }
-
- void
- do_produce(side, map)
- Side *side;
- Map *map;
- {
- notify(side, "not available yet");
- }
-
- void
- do_quit(side, map)
- Side *side;
- Map *map;
- {
- if (side->ingame) {
- if (all_others_willing_to_quit(side)) {
- /* Everbody else is willing to get out, but confirm us anyway. */
- ask_bool(side, map, "Do you really want to quit?", FALSE,
- x_kill_game);
- } else {
- if (1 /* outcome needs resolution */) {
- /* if not everybody willing to draw, then we have to resign */
- ask_bool(side, map, "Do you really want to give up?", FALSE,
- x_resign);
- } else {
- /* Everybody is just participating. */
- ask_bool(side, map, "Do you want to leave this game?", FALSE,
- x_leave_game);
- }
- }
- } else {
- /* We're already out of the game, not really anything to confirm. */
- /* (is this common to all interfaces?) */
- if (all_others_willing_to_quit(side)) {
- exit_xconq(side);
- } else {
- close_display(side);
- if (num_active_displays() == 0) {
- exit_xconq(side);
- }
- }
- }
- }
-
- static void
- x_resign(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- if (cancel)
- return;
- if (grok_bool(side, map)) {
- if (numsides > 2) {
- ask_side(side, map, "Who do you want to surrender to?", NULL,
- x_resign_2);
- } else {
- resign_game(side, NULL);
- }
- }
- }
-
- static void
- x_resign_2(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- Side *side2;
-
- if (cancel)
- return;
- grok_side(side, map, &side2);
- resign_game(side, side2);
- }
-
- /* Do the act of leaving the game. */
-
- static void
- x_leave_game(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- if (cancel)
- return;
- if (grok_bool(side, map)) {
- remove_side_from_game(side);
- /* Now go back and see what happens if we're not in the game. */
- do_quit(side, NULL);
- } else {
- /* nothing to do if we said not to exit */
- }
- }
-
- /* (Have an extra confirm for designers not to lose unsaved work?) */
-
- static void
- x_kill_game(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- if (cancel)
- return;
- if (grok_bool(side, map)) {
- exit_xconq(side);
- } else {
- /* nothing to do if we said not to exit */
- }
- }
-
- /* Center the screen on the current location. */
-
- void
- do_recenter(side, map)
- Side *side;
- Map *map;
- {
- recenter(side, map, map->curx, map->cury);
- }
-
- /* Redraw everything using the same code as when windows need a redraw. */
-
- void
- do_refresh(side, map)
- Side *side;
- Map *map;
- {
- redraw(side);
- draw_view_in_panner(side, map);
- }
-
- void
- do_remove_terrain(side, map)
- Side *side;
- Map *map;
- {
- notify(side, "can't remove terrain yet");
- }
-
- void
- do_reserve(side, map)
- Side *side;
- Map *map;
- {
- Unit *unit = map->curunit;
-
- set_unit_reserve(side, unit, TRUE, TRUE /* is this right??? */);
- }
-
- /* Set up a task to resupply the unit. */
-
- /* (should warn if task is likely to fail) */
-
- void
- do_return(side, map)
- Side *side;
- Map *map;
- {
- Unit *unit = map->curunit;
-
- /* (should doublecheck range and error out if no chance) */
- if (in_play(unit)) {
- set_resupply_task(unit);
- }
- }
-
- /* Stuff game state into a file. By default, it goes into the current
- directory. If designing a game, we can specify exactly which parts
- of the game state are to be written. */
-
- /* The command proper just sets up different modal handlers, depending on
- whether we're building (and therefore saving a scenario/fragment), or
- saving as much game state as possible, for resumption later. */
-
- void
- do_save(side, map)
- Side *side;
- Map *map;
- {
- Side *side2;
-
- /* First check to see if anybody is in the middle of doing something
- (like renaming a unit) whose state would be lost. */
- for_all_sides(side2) {
- if (side2 != side && side2->busy) {
- cmd_error(side,
- "The %s are busy doing something, can't save right now!",
- plural_form(side2->name));
- }
- }
- #ifdef DESIGNERS
- if (side->designer) {
- ask_string(side, map, "Types of data to save?", "all",
- x_save_1);
- return;
- }
- #endif /* DESIGNERS */
- if (0 /* (should be "savemustquit") */) {
- ask_bool(side, map, "You really want to save?", FALSE, x_save_2);
- } else {
- save_the_game(side);
- }
- }
-
- /* Make a module appropriate to a save file, write the file, and leave. */
-
- static void
- x_save_2(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- if (cancel)
- return;
- if (grok_bool(side, map)) {
- save_the_game(side);
- }
- }
-
- static void
- save_the_game(side)
- Side *side;
- {
- char *savename = saved_game_filename();
-
- notify_all("Game will be saved to \"%s\" ...", savename);
- if (write_entire_game_state(savename)) {
- close_displays();
- /* this should be conditional? */
- exit(0);
- } else {
- cmd_error(side, "Can't open file \"%s\"!", savename);
- }
- }
-
-
- #ifdef DESIGNERS
-
- Module *tmpmodule;
-
- static void
- x_save_1_1(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- char *filenamespec;
-
- if (cancel)
- return;
- if (grok_string(side, map, &filenamespec)) {
- tmpmodule->filename = filenamespec;
- notify(side, "File will be written to \"%s\" ...",
- tmpmodule->filename);
- if (write_game_module(tmpmodule)) {
- notify(side, "Done writing to \"%s\".", tmpmodule->filename);
- } else {
- cmd_error(side, "Can't open file \"%s\"!", tmpmodule->filename);
- }
- } else {
- map->modalhandler = x_save_1_1;
- }
- }
-
- static void
- x_save_1(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- int save;
- char *contentspec;
-
- if (cancel)
- return;
- if (grok_string(side, map, &contentspec)) {
- tmpmodule = create_game_module("game-data");
- /* Use the spec string to decide which pieces to save. */
- save = FALSE;
- if (strcmp(contentspec, "all") == 0) {
- tmpmodule->defall = TRUE;
- tmpmodule->compresslayers = TRUE;
- save = TRUE;
- } else if (strcmp(contentspec, "world") == 0) {
- tmpmodule->defworld = TRUE;
- tmpmodule->defareas = TRUE;
- tmpmodule->defareaterrain = TRUE;
- tmpmodule->defareamisc = TRUE;
- tmpmodule->defareaweather = TRUE;
- tmpmodule->defareamaterial = TRUE;
- save = TRUE;
- } else {
- cmd_error(side, "Don't understand content spec \"%s\"!",
- contentspec);
- return;
- }
- if (save) {
- ask_string(side, map, "Save data to where?", "game-data.g",
- x_save_1_1);
- } else {
- notify(side, "Nothing requested to be saved.");
- }
- } else {
- map->modalhandler = x_save_1;
- }
- }
-
- #endif /* DESIGNERS */
-
- void
- do_set_formation(side, map)
- Side *side;
- Map *map;
- {
- beep(side);
- }
-
- void
- do_sleep(side, map)
- Side *side;
- Map *map;
- {
- Unit *unit = map->curunit;
-
- set_unit_asleep(side, unit, TRUE, TRUE /* is this right??? */);
- }
-
- void
- do_survey(side, map)
- Side *side;
- Map *map;
- {
- int i;
-
- if (map->curtool == looktool) {
- map->curtool = movetool;
- set_tool_cursor(side, map);
- update_controls(side, map);
- } else if (map->curtool == movetool) {
- map->curtool = looktool;
- set_tool_cursor(side, map);
- update_controls(side, map);
- } else {
- beep(side);
- }
- }
-
- /* Take supplies from transport. */
-
- void
- do_take(side, map)
- Side *side;
- Map *map;
- {
- int something = FALSE;
- int u, u2, m, need, actual, n;
- Unit *unit = map->curunit, *unit2;
- char buf[BUFSIZE];
-
- if (nummtypes == 0) {
- cmd_error(side, "No materials in this game!");
- return;
- }
- if (!in_play(unit))
- return;
- u = unit->type;
- unit2 = unit->transport;
- if (unit2 == NULL) {
- cmd_error(side, "Nothing to take from here!");
- return;
- }
- u2 = unit2->type;
- n = (map->argint < 0 ? 1 : map->argint);
-
- buf[0] = '\0';
- for_all_material_types(m) {
- need = (n < 0 ? um_storage_x(u, m) - unit->supply[m] : n);
- if (need > 0) {
- something = TRUE;
- /* Be stingy if we're low */
- if (2 * unit2->supply[m] < um_storage_x(u2, m))
- need = max(1, need/2);
- actual = transfer_supply(unit2, unit, m, need);
- tprintf(buf, " %d %s", actual, m_type_name(m));
- }
- }
- if (something) {
- notify(side, "%s got%s.", unit_handle(side, unit), buf);
- } else {
- notify(side, "%s needed nothing.", unit_handle(side, unit));
- }
- }
-
- void
- do_take_unit(side, map)
- Side *side;
- Map *map;
- {
- notify(side, "not available yet");
- }
-
- /* Command to display the program version. */
-
- void
- do_version(side, map)
- Side *side;
- Map *map;
- {
- notify(side, "Xconq version %s", version_string());
- notify(side, "(c) %s", copyright_string());
- }
-
- void
- do_wake(side, map)
- Side *side;
- Map *map;
- {
- /* Do the curunit explicitly, might only be an occupant. */
- if (map->curunit != NULL) {
- wake_unit(map->curunit, FALSE, 0, NULL);
- draw_map_info(side, map);
- }
- /* If an argument was given, apply to all "top-level" units
- within the radius specified by the argument. */
- if (map->argint >= 0)
- wake_area(side, map->curx, map->cury, map->argint, FALSE);
- }
-
- void
- do_wake_all(side, map)
- Side *side;
- Map *map;
- {
- int n;
-
- n = (map->argint < 0 ? 0 : map->argint);
- wake_area(side, map->curx, map->cury, n, TRUE);
- }
-
- void
- do_warranty(side, map)
- Side *side;
- Map *map;
- {
- notify(side, "There is no warranty.");
- }
-
- /* X-interface-specific commands. */
-
- void
- do_embark_cmd(side, map)
- Side *side;
- Map *map;
- {
- Unit *transport, *occ;
- Unit *unit = map->curunit;
-
- if (!in_play(unit))
- return;
- /* look for the first possible transport */
- for_all_stack(unit->x, unit->y, transport) {
- /* make sure its not the transport we're in and we can enter it */
- if (transport != unit->transport &&
- valid(check_enter_action(unit, unit, transport))) {
- prep_enter_action(unit, unit, transport);
- return;
- }
-
- /* check the occupants too */
- for_all_occupants(transport, occ) {
- if (occ != unit->transport &&
- valid(check_enter_action(unit, unit, occ))) {
- prep_enter_action(unit, unit, occ);
- return;
- }
- }
- }
- cmd_error(side, "Nothing for this unit to get into!");
- }
-
- /* Toggle the "follow-action" flag. */
-
- void
- do_x_follow_action(side, map)
- Side *side;
- Map *map;
- {
- side->ui->followaction = !side->ui->followaction;
- }
-
- void
- do_x_reverse_video(side, map)
- Side *side;
- Map *map;
- {
- if (side->ui->monochrome) {
- side->ui->bonw = !side->ui->bonw;
- set_colors(side);
- reset_color_state(side);
- redraw(side);
- } else {
- cmd_error(side, "Reverse video is only for monochrome!");
- }
- }
-
- /* (should clone last map in list perhaps) */
-
- void
- do_x_map(side, map)
- Side *side;
- Map *map;
- {
- Map *map2;
-
- map2 = create_map(side, 5, NULL);
- }
-
- void
- do_x_world_map(side, map)
- Side *side;
- Map *map;
- {
- Map *wmap;
-
- wmap = create_map(side, -1, NULL);
- }
-
- void
- do_zoom_in(side, map)
- Side *side;
- Map *map;
- {
- zoom_in_out(side, map, ZOOM_IN);
- }
-
- void
- do_zoom_out(side, map)
- Side *side;
- Map *map;
- {
- zoom_in_out(side, map, ZOOM_OUT);
- }
-
- #ifdef DESIGNERS
-
- static void x_design PROTO ((Side *side, Map *map, int cancel));
- static void x_set_terrain_type PROTO ((Side *side, Map *map, int cancel));
- static void x_set_unit_type PROTO ((Side *side, Map *map, int cancel));
- static int check_designer_status PROTO ((Side *side, char *str));
-
- int designed_on = FALSE;
-
- void enable_in_unit_type_list PROTO ((Side *side, Map *map, int u, int flag));
-
- static void really_do_design PROTO ((Side *side));
-
- void
- do_design(side, map)
- Side *side;
- Map *map;
- {
- int u;
- Map *map2;
-
- if (!side->designer) {
- if (!designed_on) {
- ask_bool(side, map, "Do you really want to start designing?",
- FALSE, x_design);
- } else {
- really_do_design(side);
- }
- } else {
- become_nondesigner(side);
- side->ui->mayseeall = (g_see_all() || endofgame);
- for_all_maps(side, map2) {
- map2->seeall = side->ui->mayseeall;
- update_controls(side, map2);
- for_all_unit_types(u) {
- enable_in_unit_type_list(side, map2, u, FALSE);
- }
- }
- popdown_design(side);
- }
- }
-
- static void
- x_design(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- if (cancel)
- return;
- if (grok_bool(side, map)) {
- really_do_design(side);
- } else {
- /* nothing to do if we said not to design */
- }
- }
-
- static void
- really_do_design(side)
- Side *side;
- {
- int u;
- Map *map2;
-
- become_designer(side);
- side->ui->mayseeall = TRUE;
- for_all_maps(side, map2) {
- map2->seeall = side->ui->mayseeall;
- update_controls(side, map2);
- for_all_unit_types(u) {
- enable_in_unit_type_list(side, map2, u, TRUE);
- }
- }
- popup_design(side);
- }
-
- static int
- check_designer_status(side, str)
- Side *side;
- char *str;
- {
- if (side->designer) {
- return TRUE;
- } else {
- cmd_error(side, "You're not a designer, can't %s!", str);
- return FALSE;
- }
- }
-
- void
- do_x_set_terrain_type(side, map)
- Side *side;
- Map *map;
- {
- int n = 0;
- int numtypes;
-
- if (!check_designer_status(side, "set terr paint type"))
- return;
- numtypes = ask_terrain_type(side, map, "Type to paint: ", NULL,
- x_set_terrain_type);
- switch (numtypes) {
- case 0:
- beep(side);
- break;
- case 1:
- side->ui->curttype = map->tvec[0];
- if (map->argint >= 0)
- side->ui->curbrushradius = map->argint;
- notify(side, "will now be painting %d-radius %s.",
- side->ui->curbrushradius, t_type_name(side->ui->curttype));
- break;
- default:
- break;
- }
- }
-
- static void
- x_set_terrain_type(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- int t2;
-
- if (cancel)
- return;
- if (map->inpch == '?') {
- notify(side, "Not being helpful yet.");
- map->modalhandler = x_set_terrain_type;
- return;
- }
- if (grok_terrain_type(side, map, &t2)) {
- if (t2 != NONUTYPE) {
- side->ui->curttype = t2;
- if (map->argint >= 0)
- side->ui->curbrushradius = map->argint;
- notify(side, "will now be painting %d-radius %s.",
- side->ui->curbrushradius, t_type_name(side->ui->curttype));
- }
- } else {
- /* beep? */
- }
- }
-
- /* Command to paint terrain. */
-
- void
- do_x_paint_terrain(side, map)
- Side *side;
- Map *map;
- {
- if (!check_designer_status(side, "paint terrain"))
- return;
- paint_cell(side, map->curx, map->cury,
- side->ui->curbrushradius, side->ui->curttype);
- }
-
- /* Command to set the current unit type to create. */
-
- void
- do_x_set_unit_type(side, map)
- Side *side;
- Map *map;
- {
- int numtypes;
-
- if (!check_designer_status(side, "set unit type"))
- return;
- numtypes = ask_unit_type(side, map, "Type to create: ", NULL,
- x_set_unit_type);
- switch (numtypes) {
- case 0:
- beep(side);
- break;
- case 1:
- side->ui->curutype = map->uvec[0];
- if (map->argint >= 0)
- side->ui->cursidenumber = map->argint;
- notify(side, "will now be creating %s %s units",
- side_adjective(side_n(side->ui->curusidenumber)),
- u_type_name(side->ui->curutype));
- break;
- default:
- break;
- }
- }
-
- static void
- x_set_unit_type(side, map, cancel)
- Side *side;
- Map *map;
- int cancel;
- {
- int u2;
-
- if (cancel)
- return;
- if (map->inpch == '?') {
- notify(side, "Not being helpful yet.");
- map->modalhandler = x_set_unit_type;
- return;
- }
- if (grok_unit_type(side, map, &u2)) {
- if (u2 != NONUTYPE) {
- side->ui->curutype = u2;
- if (map->argint >= 0)
- side->ui->cursidenumber = map->argint;
- notify(side, "will now be creating side %d %s units",
- side->ui->cursidenumber, u_type_name(side->ui->curutype));
- }
- } else {
- /* beep? */
- }
- }
-
- /* Command to create and place a unit. */
-
- void
- do_x_add_unit(side, map)
- Side *side;
- Map *map;
- {
- Unit *unit;
-
- if (!check_designer_status(side, "create units"))
- return;
- unit = designer_create_unit(side,
- side->ui->curutype, side->ui->cursidenumber,
- map->curx, map->cury);
- if (unit != NULL) {
- set_current_unit(side, map, unit);
- } else {
- cmd_error(side, "Unit creation failed!");
- }
- }
-
- #endif /* DESIGNERS */
-
- #ifdef DEBUGGING
-
- /* Debugging-related commands. */
-
- /* General debugging toggles. */
-
- void
- do_debug(side, map)
- Side *side;
- Map *map;
- {
- #ifndef Debug
- Debug = !Debug;
- #endif
- }
-
- void
- do_debugg(side, map)
- Side *side;
- Map *map;
- {
- #ifndef DebugG
- DebugG = !DebugG;
- #endif
- XSynchronize(side->ui->dpy, DebugG);
- }
-
- void
- do_debugm(side, map)
- Side *side;
- Map *map;
- {
- #ifndef DebugM
- DebugM = !DebugM;
- #endif
- }
-
- /* Pretend to be a monochrome screen - use for comparing color
- and b/w appearance of screens. */
-
- void
- do_x_fake_mono(side, map)
- Side *side;
- Map *map;
- {
- side->ui->monochrome = !side->ui->monochrome;
- side->ui->bonw = BLACKONWHITE;
- set_colors(side);
- reset_color_state(side);
- redraw(side);
- }
-
- #endif /* DEBUGGING */
-
- /* Generic command error feedback. */
-
- static void
- #ifdef __STDC__
- cmd_error(Side *side, char *fmt, ...)
- #else
- cmd_error(side, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
- Side *side;
- char *fmt;
- long a1, a2, a3, a4, a5, a6, a7, a8, a9;
- #endif
- {
- char tmpnbuf[BUFSIZE];
-
- #ifdef __STDC__
- {
- va_list ap;
-
- va_start(ap, fmt);
- vsprintf(tmpnbuf, fmt, ap);
- va_end(ap);
- }
- #else
- sprintf(tmpnbuf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
- #endif
- low_notify(side, tmpnbuf);
- /* Only beep once, even if a command generates multiple error messages. */
- if (side->ui->beepcount++ < 1)
- beep(side);
- }
-